import requests
from flask import current_app, session
from requests.exceptions import RequestException

def callApi(endpoint: str, token: dict, method: str ='GET', data: any = None, params: dict = None) -> any:
    """
    一个通用的调用内部 API 的辅助函数
    Args:
        endpoint (str): API 的端点路径，例如 '/users'
        method (str): HTTP 方法，'GET', 'POST' 等
        data (dict): 用于 POST/PUT 的 JSON 数据
        params (dict): URL 查询参数

    Returns:
        dict|list: 成功时返回 API 响应的 JSON 数据
        None: 请求失败时返回 None
    """
    # 从配置中构建完整的 URL
    url = f"{current_app.config['API_BASE_URL']}{endpoint}"
    
    if not token.get('token'):
        current_app.logger.error("Token is missing or invalid")
        return None
    # 设置认证请求头（根据你的 API 要求调整）
    token = token.get('token')
    headers = {
        'Authorization': f'Bearer {token}',
        'Content-Type': 'application/json'
    }
    
    try:
        response = requests.request(
            method=method,
            url=url,
            headers=headers,
            json=data,   # 使用 json 参数，requests 会自动序列化并设置 Content-Type
            params=params,
            timeout=30   # 设置超时时间
        )
        # 检查是否需要刷新 token
        if response.status_code == 401:
            try:
                response_data = response.json()
                if response_data.get('error_code') == 20001:
                    # Token 过期，尝试刷新
                    new_token = refresh_token(token.get('refresh_token'))
                    if new_token:
                        # 更新 session 中的 token
                        session['token'] = new_token
                        # 使用新 token 重新发起请求
                        headers['Authorization'] = f'Bearer {new_token["token"]}'
                        
                        response = requests.request(
                            method=method,
                            url=url,
                            headers=headers,
                            json=data,
                            params=params,
                            timeout=30
                        )
                        response.raise_for_status()
                    else:
                        current_app.logger.error("Token refresh failed")
                        return None
            except (ValueError, KeyError):
                # 如果不是 JSON 响应或者没有 error_code，继续抛出异常
                pass
        
        response.raise_for_status()
        # 如果状态码不是 2xx，引发异常或处理错误
        response.raise_for_status()
        if response.content:
            return response.json()
        else:
            return None
    except RequestException as e:
        current_app.logger.error(f"API request failed to {url}: {e}")
        return None
    
def refresh_token(refresh_token: str) -> dict:
    """
    使用 refresh token 获取新的 access token
    
    Args:
        refresh_token (str): 刷新令牌
        
    Returns:
        dict: 包含新 token 的字典，失败返回 None
    """
    if not refresh_token:
        current_app.logger.error("Refresh token is missing")
        return None
    
    refresh_url = f"{current_app.config['API_BASE_URL']}/users/refresh"
    
    headers = {
        'Content-Type': 'application/json'
    }
    
    data = {
        'refresh_token': refresh_token
    }
    
    try:
        response = requests.post(
            url=refresh_url,
            headers=headers,
            json=data,
            timeout=30
        )
        response.raise_for_status()
        
        return response.json()
        
    except RequestException as e:
        current_app.logger.error(f"Token refresh failed: {e}")
        return None